'use strict';

const path = require('path');
const semver = require('semver');
const colors = require('colors/safe');
const userHome = require('user-home');
const pathExists = require('path-exists').sync;
const commander = require('commander');
const pkg = require('../package.json');
const log = require('@test-hy-in/log');
const init = require('@test-hy-in/init');
const constant = require('./const.js');
const exec = require('@test-hy-in/exec');

// let args;

const program = new commander.Command();

async function core() {
    try{
        // cli准备
        await prepare()
        // cli注册命令
        registerCommand()

    }catch(e){
        log.error(e.message)
        if(process.env.LOG_LEVEL === 'verbose'){
            console.log(e)
        }
    }
}

// 检查cli的版本号
function checkPkgVersion(){
    log.success('版本',pkg.version)
}

// 检查root账号
function checkRoot(){
    const rootCheck = require('root-check');
    // console.log('root前：',process.geteuid())
    rootCheck();
    // console.log('root后：',process.geteuid())
}

// 检查用户主目录
function checkUserHome(){
    if(!userHome || !pathExists(userHome)){
        throw new Error(colors.red('当前登录用户主目录不存在！'))
    };
}

// 解析获取入参并设置是否开启debug模式
// function checkInputArgs(){
//     const minimist = require('minimist');
//     args = minimist(process.argv.slice(2));
//     checkArgs()
// }

// 检查入参参数并设置debug模式
// function checkArgs(){
//     if(args.debug){
//         process.env.LOWEST_NODE_VERSION = 'verbose';
//     }else{
//         process.env.LOWEST_NODE_VERSION = 'info';
//     };
//     log.level = process.env.LOWEST_NODE_VERSION;
// }

// 通过.env文件来将值存储在环境变量中
function checkEnv(){
    const dotenv = require('dotenv');
    const dotenvPath = path.resolve(userHome,'.env');
    if(pathExists(dotenvPath)){
        dotenv.config({
            path:dotenvPath
        });
    };
    createDefaultConfig();
}

// 为cli创建一个初始默认的.env环境变量config
function createDefaultConfig(){
    const cliConfig = {
        home:userHome
    };
    if(process.env.CLI_HOME){
        cliConfig['cliHome'] = path.join(userHome,process.env.CLI_HOME)
    }else{
        cliConfig['cliHome'] = path.join(userHome,constant.DEFAULT_CLI_HOME)
    }
    process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

// 检查cli版本，如果较老可以通过npm进行更新
async function checkGlobalUpdata(){
    // 1、获取当前版本号和模块名
    // 2、调用npm API，获取所有版本号
    // 3、提取所有版本号，比对有哪些大于当前版本的版本号
    // 4、将大于当前的版本号中最新的一个版本号提取出来并提示用户去更新
    const currentVersion = pkg.version;
    const npmName = pkg.name;
    const { getNpmServerVersion } = require('@test-hy-in/get-npm-info');
    const lastVersion = await getNpmServerVersion(npmName,currentVersion);
    if(lastVersion&&semver.gt(lastVersion,currentVersion)){
        log.warn(colors.yellow(`请手动更新${npmName}，当前版本为${currentVersion}，最新版本为${lastVersion}
        更新命令为：npm install -g ${npmName}`))
    }
}

// 初始前准备
async function prepare(){
    checkPkgVersion();
    checkRoot();
    checkUserHome();
    checkEnv();
    await checkGlobalUpdata();
}

// 注册脚手架命令
function registerCommand(){
    // 全局
    program
        .name(Object.keys(pkg.bin)[0])
        .usage('<command> [options]')
        .version(pkg.version)
        .option('-d, --debug','是否开启调试模式',false)
        .option('-tp, --targetPath <targetPath>','是否指定本地目录','')
    
    program
        .command('init [projectName]')
        .option('-f, --force','是否强制初始化项目')
        .action(exec)

    program.on('option:debug',function(){
        if(program.debug){
            process.env.LOG_LEVEL = 'verbose';
        }else{
            process.env.LOG_LEVEL = 'info'
        }
        log.level = process.env.LOG_LEVEL;
    })

    program.on('option:targetPath',function(){
        process.env.CLI_TARGET_PATH = program.targetPath;
    })

    program.on('command:*',function(obj){
        const availableCommands = program.commands.map(cmd=>{
            cmd.name()
        });
        console.log(colors.red('未知指令：'+obj[0]));
        if(availableCommands.length>0){
            console.log(colors.red('可用指令：'+availableCommands.join(',')))
        }
    })

    program.parse(process.argv)

    if(program.args && program.args.length<1){
        program.outputHelp();
        console.log()
    }    
}

module.exports = core;